import * as fs from 'fs';
import * as XLSX from 'xlsx';
import * as process from 'process';
import * as path from 'path';
import msgpack from 'msgpack5';
import zlib from 'zlib';
//指定需要读取的表格根目录路径
let readTableDirPath = process.argv[2]

//指定表格打包之后的数据文件输出的路径
let outputPath = process.argv[3];
let defPath = process.argv[4];
let cs = process.argv[5] || "c";

let fileObj: any = {};
class Main {
    constructor() {
        this.init();
    }

    private init() {
        const files = fs.readdirSync(readTableDirPath, "utf-8");
        files.forEach(file => {
            const filePath = path.join(readTableDirPath, file);
            const stat = fs.statSync(filePath);
            if (stat.isDirectory()) {
                // traverseFolder(filePath); // 递归遍历子文件夹
            } else {
                if (filePath.indexOf('.xlsx') >= 0 && filePath.indexOf('$') == -1) {
                    this.readxlsx(filePath);
                }
            }
        });
        console.log("导出完成");

        console.log("开始压缩");
        let output = msgpack().encode(fileObj) as any;

        fs.writeFileSync(`${outputPath}/config.obj`, output);

        let compressedData = zlib.gzipSync(output);
        fs.writeFileSync(`${outputPath}/config.obj`, output);
        fs.writeFileSync(`${outputPath}/config.obj.gzip`, compressedData);


    

        // console.log(msgpack().decode(zlib.gunzipSync(fs.readFileSync(`${outputPath}/ZuoBiaoCfg.obj.gzip`))));

        // let d = msgpack().decode(zlib.gunzipSync(compressedData))

        // for (let key in d) {
        //     console.log(msgpack().decode(d[key]))
        // }
    }

    readxlsx(path: string) {
        const workbook = XLSX.readFile(path);
        const sheetNames = workbook.SheetNames;

        for (let i = 0; i < sheetNames.length; i++) {
            const sheetName = sheetNames[i];
            const worksheet = workbook.Sheets[sheetName];

            if (worksheet['!ref'] === undefined) {
                continue;
            }
            //第一行为空则不读取
            if (worksheet['!ref'].indexOf('A1') == -1) {
                continue;
            }

            console.log("正在导出：", path + "/" + sheetName);
            const data0 = XLSX.utils.sheet_to_json(worksheet, { header: 1, raw: true }) as any[][];

            let desArr = data0.shift() || [];
            let scArr = data0.shift() || [];
            let typeArr = data0.shift() || [];
            let keyArr = data0.shift() || [];
            let pushKeyArr = [];//需要的key
            let pushTypeArr = [];//需要的类型
            let filterKeyArr = [];//排除的key
            for (let i = 0; i < scArr.length; i++) {
                if (scArr[i].indexOf(cs) == -1) {
                    filterKeyArr.push(keyArr[i]);
                    continue;
                }
                pushKeyArr.push(keyArr[i]);
                pushTypeArr.push(typeArr[i]);
            }

            const data = XLSX.utils.sheet_to_json(worksheet, { range: 3, raw: true, defval: "" }) as any[][];
            this.formadefaultType(data, keyArr, typeArr)


            this.writeConfiguration(pushKeyArr, pushTypeArr, sheetName);
            this.filterScData(filterKeyArr, data);

            let d = JSON.stringify(data)
            // fs.writeFileSync(`${outputPath}/${sheetName}.json`, d);
            let output = msgpack().encode(d) as any;
            // fs.writeFileSync(`${outputPath}/${sheetName}.obj`, output);
            if (sheetName.indexOf("map") >= 0) {
                // console.log(data)
            }
            fileObj[sheetName] = output;
        }
    }

    filterScData(filterKeyArr: number[], data: any[]): any[] {
        for (let i = 0; i < data.length; i++) {
            for (let j = 0; j < filterKeyArr.length; j++) {
                delete data[i][filterKeyArr[j]];
            }
        }
        return data
    }

    formadefaultType(data: any[], keyArr: string[], typeArr: string[]): any[] {
        return data.map((item, index) => {
            for (let i = 0; i < keyArr.length; i++) {
                if (item[keyArr[i]] === "") {
                    let type = typeArr[i];
                    let defaultValue;
                    switch (type) {
                        case "number":
                            defaultValue = 0;
                            break;
                        case "string":
                            defaultValue = "";
                            break;
                        case "number[]":
                            defaultValue = [];
                            break;
                        case "string[]":
                            defaultValue = [];
                            break;
                        case "number[][]":
                            defaultValue = [[]];
                            break;
                        case "string[][]":
                            defaultValue = [[]];
                            break;
                        default:
                            defaultValue = null;
                    }
                    item[keyArr[i]] = defaultValue;
                }
            }
        }
        )
    }

    writeConfiguration(keyArr: string[] = [], typeArr: string[] = [], sheetName: string = ""): void {
        let result = "declare namespace ConfigDef {\n";
        result += `\texport interface ${sheetName} {\n`;
        for (let i = 0; i < keyArr.length; i++) {
            result += `\t\t${keyArr[i]}: ${typeArr[i]};\n`;
        }
        result += `\t}\n`;
        result += `}`;
        fs.writeFileSync(`${defPath}/${sheetName}Cfg.d.ts`, result);
    }

}

new Main();

